/** 基于邻接矩阵实现的无向图类 */

class GraphAdjMat {
    #vertices; // 顶点列表，保存顶点值
    #adjMat; // 邻接矩阵，二维数组,存储各个顶点之间边的关系 0-无边 1-有边

    constructor(vertices, edges) { //传进来的vertices是顶点数组[6,3,2,4,1],edges是边列表[[0,1],[0,2],[1,2],[1,3],[2,4]],值是顶点的索引
        this.#vertices = [];
        this.#adjMat =  [];
        // 添加顶点
        for(const value of vertices){
            this.addVertex(value);
        }
        //添加边
        for(const [i,j] of edges){
            this.addEdge(i,j);
        }
    }

    /**
     * 获取顶点的数量
     */
    size(){
        return this.#vertices.length;
    }

    /**
     * 添加顶点的方法
     */
    addVertex(val){
        const n = this.size(); // 获取当前顶点数量
        this.#vertices.push(val); //向顶点列表中增加一个新的顶点的值
        const newRow = [];//创建新的行
        for(let i = 0 ; i < n; i++){//有多少行说明就有多少列,给新增加的这一行的每一列都初始化为0
            newRow.push(0);
        }
        this.#adjMat.push(newRow); //将新行添加到邻接矩阵中
        for(const row of this.#adjMat){
            row.push(0); //在每一行末尾添加一个0,新加了一行,对应的在每一行中新加一列
        }
    }

    /**
     * 删除顶点的方法
     */
    removeVertex(index){ //删除一个下标为index的顶点
        if(index<0 || index > this.size()-1){
            throw new Error('顶点索引越界,请检查索引值');
        }
        //删除顶点
        this.#vertices.splice(index,1); 
        //删除邻接矩阵中对应的行
        this.#adjMat.splice(index,1);
        //删除邻接矩阵中对应的列
        for(const row of this.#adjMat){
            row.splice(index,1);
        }
    }

    /**
     * 添加边的方法
     */
    addEdge(i,j){
        //异常值处理
        if(i < 0 || i >= this.size() || j < 0 || j >= this.size()){
            throw new Error('顶点索引越界,请检查索引值');
        }
        //添加边
        this.#adjMat[i][j] = 1;
        this.#adjMat[j][i] = 1;
    }

    /**
     * 删除边的方法
     */
    remoteEdge(i,j){
        if(i < 0 || i >= this.size() || j < 0 || j >= this.size()){
            throw new Error('顶点索引越界,请检查索引值');
        }
        if(this.#adjMat[i][j] === 0){
            throw new Error('边不存在,无法删除');
        }
        //删除边
        this.#adjMat[i][j] = 0;
        this.#adjMat[j][i] = 0;
    }

    /**
     * 打印图的方法
     */
    print(){
        console.log('顶点列表:',this.#vertices);
        console.log('邻接矩阵:');
        for(const row of this.#adjMat){
            console.log(row.join(' ')+'\n');
        }
        console.log('--------------------------------');
    }
}



const myGraph = new GraphAdjMat([6,3,2,4,1],[[0,1],[0,2],[1,2],[1,3],[2,4]]);
myGraph.print();

// 测试添加一个节点
myGraph.addVertex(5);
myGraph.print();

//测试添加一条边
myGraph.addEdge(0,5);
myGraph.print();

//测试删除一条边
myGraph.remoteEdge(0,5);
myGraph.print();

//测试删除一个节点
myGraph.removeVertex(5);
myGraph.print();